package com.mzx.javase.集合;

import com.sun.javafx.tk.PrintPipeline;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Objects;
import java.util.Set;

/**
 * 类描述：
 *
 * @ClassName HashSetTest01
 * @Description TODO
 * @Author 69417
 * @Date 2022/7/12 14:22
 * @Version 1.0
 */
public class HashSetTest01 {
    public static void main(String[] args) {
        Set<String> hashSet = new HashSet<>();
        hashSet.add("zhansan");
        hashSet.add("lisi");
        hashSet.add("wangwu");
        hashSet.add("zhaoli");
        System.out.println("hashset为："+ hashSet);
        //由此发现，放在hashset集合中的元素，放进去和取出来的顺序是不一样的;且不重复
        //因为hashset存放的元素是hashmap集合的key部分
        /*hashmap底层是数据+链表的数据结构，默认初始化为一个16个长度的空数组，数组下分别挂着一个链表(和珠珠帘类似)，
        默认加载因子为0.75(当底层数组长度达到整个长度的0.75时)，会自动扩容，扩容为原来的2倍。

        存放原理：当添加一个元素到hashmap集合中，首先计算hashmap的key的hashcode值，再将hashcode通过哈希算法，转化为
        下标，存放到数组中；如果对应下标的数组有元素时(证明他们的hashcode相等，应该在去比较equals)，再将key的equals和数组上的值进行比较；如果相等，直接覆盖值；
        若equals不相等：数组下表有值，且指向的单向链表上没有值，则直接增加；

        在jdk8之后。数组下表所对应的链表长度如果超过了8，则转化为红黑树，如果没有超过8，则转化为单向链表

        * */
        //使用自定义的Student类,因为集合中存放的是对象的内存地址，如果想让内容一致，则认为存放元素一致，需要重写存放类的hashcode和equals方法
        HashSet<Student> studentHashSet = new HashSet<>();
        studentHashSet.add(new Student("zhangsan", 20));
        studentHashSet.add(new Student("lisi", 18));
        studentHashSet.add(new Student("zhangsan", 20));
        Iterator<Student> iterator = studentHashSet.iterator();
        while (iterator.hasNext()) {
            Student student = iterator.next();
            System.out.println("从hashSet中取出的Student对象为" + student);
        }

    }
}
//自定义一个类
class Student{
    private String name;
    private int age;

    public Student() {
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age && Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
